﻿using System;
using System.Collections.Generic;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Markup;

using agree.schema;

using alib;
using alib.Collections;
using alib.Debugging;
using alib.Enumerable;

namespace agree
{
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	/// <summary>
	/// control harness for a parse operation
	/// </summary>
	///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
	[DisplayName("Parse Control Instance")]
	public partial class ParseControl : ChartControl<ParseControl, ChartSpan>,
		ρρSourceItem
	{
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		/// <summary>
		///
		/// </summary>
		///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
		public ParseControl(IRtParent trace, IActiveObj<IChartObj<ChartSpan>> items)
			: base(trace, items)
		{
			//: base(ctrl, ctrl.config.Parser.Chart, Tfs.Flags.None)
			//, g.AgreeConfig.Parser.Chart.Job, g._parser_start_symbols, items, cd)Grammar g, , ChartDebugger cd = null
		}

		ChartCell[][] chart;

		///////////////////////////////////////////////////////////////////////
		///
		IString source_item;
		public IString SourceItem
		{
			get { return source_item; }
			set { throw not.valid; }
		}
		///
		///////////////////////////////////////////////////////////////////////

		ReppExecutor repp;
		public ReppExecutor ReppExecutor
		{
			get { return repp; }
		}

		MappingTokenBuilder mtb;
		public MappingTokenBuilder MappingTokenBuilder
		{
			get { return mtb; }
		}

		TokenMappingLattice tmlat;
		public TokenMappingLattice TokenMappingLattice
		{
			get { return tmlat; }
		}

		MorphologyExecutor morph;
		public MorphologyExecutor MorphologyExecutor
		{
			get { return morph; }
		}

		LexicalFilterExecutor lfm;
		public LexicalFilterExecutor LexicalFilterExecutor
		{
			get { return lfm; }
		}

		LexicalFilteringRewriter lfr;
		public LexicalFilteringRewriter LexicalFilteringRewriter
		{
			get { return lfr; }
		}

		ChartDependenciesLoader deps;
		public ChartDependenciesLoader ChartDependenciesLoader
		{
			get { return deps; }
		}

		protected override void Initialize()
		{
			//this.source_item = (IString)P.SourceItem.FindTracePropertyValue(this);
			this.source_item = (IString)this.FindTrace<IString>();
			if (source_item == null)
				source_item = this.FindTrace<IString>();

			this.repp = (ReppExecutor)this.FindTrace<ReppExecutor>();

			this.mtb = (MappingTokenBuilder)this.FindTrace<MappingTokenBuilder>();

			this.tmlat = (TokenMappingLattice)this.FindTrace<TokenMappingLattice>();

			this.morph = (MorphologyExecutor)this.FindTrace<MorphologyExecutor>();

			this.lfm = (LexicalFilterExecutor)this.FindTrace<LexicalFilterExecutor>();

			this.lfr = (LexicalFilteringRewriter)this.FindTrace<LexicalFilteringRewriter>();

			this.deps = (ChartDependenciesLoader)this.FindTrace<ChartDependenciesLoader>();

			int size = (int)P.MinimalSpanCount.FindTracePropertyValue(this);

			if ((base.spanning_count = size) <= 0)
				return;

			if ((rules = rules ?? tu.em.ParserRules) == null || rules.Length == 0)
				return;

			if ((rgss = rgss ?? tu.em.ParserStartSymbols) == null || rgss.Length == 0)
				return;

			base.rr = u.ftm.ParseRestrictors;

			this.chart = new ChartCell[spanning_count][];
			for (int i = 0; i < spanning_count; i++)
			{
				ChartCell[] cc = chart[i] = new ChartCell[spanning_count - i];
				for (int j = 0; j < spanning_count - i; j++)
					cc[j] = new ChartCell();
			}
			base.spanning_cell = chart[0][spanning_count - 1];

			int cae = (spanning_count - 1) << 1;
			this.rgns = new NotificationSource[cae];
			for (int j = 0; j < cae; j++)
				rgns[j] = new NotificationSource(this, false);
		}
	};
}
